#include "TestDriverApp.h"

#include "EventString.h"

#include <stdlib.h>
#include <string.h>

static void
driver_app_finalize(DriverApp *object)
{
	event_file_driver_finalize(EVENT_FILE_DRIVER(object));
	event_object_unref(object->data_head);
}

static int
driver_app_parser(EventFileDriver *driver, epointer data, int length)
{
	char	    *buf;
	DriverApp   *app = DRIVER_APP(driver);
	EventString *str;

	if (!app->data_head) {
		app->data_head = event_node_new();
		app->data_end  = app->data_head;
		app->data_iter = app->data_head;
	}

	buf	    = (char *)malloc(length + 1);
	buf[length] = '\0';
	memcpy(buf, data, length);
	str = event_string_new(buf);
	free(buf);
	event_node_set_data(app->data_end, str, event_object_unref);
	event_node_set_next(app->data_end, event_node_new());
	app->data_end = app->data_end->next;
	return 0;
}

static EventFileDriverPack *
driver_app_writer(EventFileDriver *driver)
{
	char	    *buffer;
	DriverApp   *app = DRIVER_APP(driver);
	EventString *str;
	static bool  is_first_try = true;

	if (is_first_try) {
		app->data_iter = app->data_head;
		is_first_try   = false;
	}

	if (!app->data_iter)
		return NULL;

	str	       = EVENT_STRING(app->data_iter->data);
	app->data_iter = app->data_iter->next;
	buffer	       = (char *)malloc(str->length);
	memcpy(buffer, str->string, str->length);

	return event_file_driver_pack_new(buffer, str->length);
}

DriverApp *
driver_app_new()
{
	DriverApp *object = MALLOC_NEW(DriverApp);

	event_file_driver_init(EVENT_FILE_DRIVER(object));
	event_object_set_finalize(object, FINALIZE(driver_app_finalize));

	event_file_driver_set_parser(EVENT_FILE_DRIVER(object),
				     driver_app_parser);
	event_file_driver_set_writer(EVENT_FILE_DRIVER(object),
				     driver_app_writer, NULL);

	object->data_head = object->data_end = NULL;
	object->data_iter		     = NULL;

	return object;
}

void
driver_app_add_item(DriverApp *app, const char *item)
{
	EventString *str = event_string_new(item);

	if (!app->data_end)
		app->data_head = app->data_end = event_node_new();

	event_node_set_data(app->data_end, str, event_object_unref);
	event_file_driver_add_count_once(EVENT_FILE_DRIVER(app));
	event_node_set_next(app->data_end, event_node_new());
	app->data_end = app->data_end->next;
}